KCL/AOS is equipped with a screen editor FeCl2 (Full-screen Editor as a Common Lisp TOOl). FeCl2 is an EMACS-like editor with facilities for Lisp coding. FeCl2 is invoked from KCL by the function ed and the result of editing can be passed to KCL directly. For the details of FeCl2 refer to The FeCl2 Editor Reference Manual.
ed &optional filename[Function]
The FeCl2 editor is not supported by other versions of KCL. The function ed of KCL/VAX, KCL/SUN, and KCL/UST calls the vi editor. If you hate vi, define your own ed function using the function system described in Chapter 8.
The following table lists all symbols defined in KCL. Each line has the following form.
symbol [kind] remark
where kind is Function, Macro, Special (i.e., Special form name), Variable, Constant, Symbol, or Keyword. In the table, some symbols are labeled both as a macro and a special form name. This means that, although these symbols are defined to be a macro name in the Common Lisp Reference Manual , KCL treats them as if they were special forms (see Section 9.1). The pages in the remark refer to pages in this report.
* [Function] * [Variable] ** [Variable] *** [Variable] + [Function] + [Variable] ++ [Variable] +++ [Variable] - [Function] - [Variable] / [Function] / [Variable] // [Variable] /// [Variable] /= [Function] 1+ [Function] 1- [Function] < [Function] <= [Function] = [Function] > [Function] >= [Function] :abort [Keyword] abs [Function] acons [Function] acos [Function] acosh [Function] adjoin [Function] adjust-array [Function]
:adjustable [Keyword] adjustable-array-p [Function] allocate [Function] Added. allocate-contiguous-pages [Function] Added. allocated-contiguous-pages [Function] Added. allocated-pages [Function] Added. allocated-relocatable-pages [Function] Added. allocate-relocatable-pages [Function] Added. alpha-char-p [Function] alphanumericp [Function] and [Special, Macro] append [Function] :append [Keyword] apply [Function] applyhook [Function] *applyhook* [Variable] apropos [Function] apropos-list [Function] aref [Function] :array [Keyword] array-dimension [Function] array-dimension-limit [Constant] array-dimensions [Function] array-element-type [Function] array-has-fill-pointer-p [Function] array-in-bounds-p [Function] array-rank [Function] array-rank-limit [Constant] array-row-major-index [Function] array-total-size [Function] array-total-size-limit [Constant] arrayp [Function] ash [Function] asin [Function] asinh [Function] assert [Macro] assoc [Function] assoc-if [Function] assoc-if-not [Function] atan [Function]
atanh [Function] atom [Function] :b [Keyword] Abbreviate Break Loop Command. :backtrace [Keyword] Break Loop Command. :base [Keyword] bit [Function] bit-and [Function] bit-andc1 [Function] bit-andc2 [Function] bit-eqv [Function] bit-ior [Function] bit-nand [Function] bit-nor [Function] bit-not [Function] bit-orc1 [Function] bit-orc2 [Function] bit-vector-p [Function] bit-xor [Function] block [Special] :block [Keyword] Added. :blocks [Keyword] Break Loop Command. boole [Function] boole-1 [Constant] boole-2 [Constant] boole-and [Constant] boole-andc1 [Constant] boole-andc2 [Constant] boole-c1 [Constant] boole-c2 [Constant] boole-clr [Constant] boole-eqv [Constant] boole-ior [Constant] boole-nand [Constant] boole-nor [Constant] boole-orc1 [Constant] boole-orc2 [Constant] boole-set [Constant] boole-xor [Constant] both-case-p [Function] boundp [Function]
break [Function] *break-on-warnings* [Variable] *break-enable* [Variable] Added. butlast [Function] by [Function] Added. bye [Function] Added. byte [Function] byte-position [Function] byte-size [Function] :c [Keyword] Abbreviated Break Loop Command. caaaar [Function] caaadr [Function] caaar [Function] caadar [Function] caaddr [Function] caadr [Function] caar [Function] cadaar [Function] cadadr [Function] cadar [Function] caddar [Function] cadddr [Function] caddr [Function] cadr [Function] call-arguments-limit [Constant] car [Function] :case [Keyword] case [Special, Macro] catch [Special] ccase [Macro] cdaaar [Function] cdaadr [Function] cdaar [Function] cdadar [Function] cdaddr [Function] cdadr [Function] cdar [Function] cddaar [Function] cddadr [Function] cddar [Function]
cdddar [Function] cddddr [Function] cdddr [Function] cddr [Function] cdr [Function] ceiling [Function] cerror [Function] :c-file [Keyword] Added. char [Function] char-bit [Function] char-bits [Function] char-bits-limit [Constant] char-code [Function] char-code-limit [Constant] char-control-bit [Constant] char-downcase [Function] char-equal [Function] char-font [Function] char-font-limit [Constant] char-greaterp [Function] char-hyper-bit [Constant] char-int [Function] char-lessp [Function] char-meta-bit [Constant] char-name [Function] char-not-equal [Function] char-not-greaterp [Function] char-not-lessp [Function] char-super-bit [Constant] char-upcase [Function] char/= [Function] char< [Function] char<= [Function] char= [Function] char> [Function] char>= [Function] character [Function] characterp [Function] check-type [Macro] :circle [Keyword]
cis [Function] clear-input [Function] Different. clear-output [Function] Different. clines [Macro] Added. close [Function] Different. clrhash [Function] code-char [Function] coerce [Function] commonp [Function] compilation-speed [Symbol] Optimize Quality. compile [Function] compile-file [Function] compiled-function-p [Function] compiler-let [Special] complex [Function] complexp [Function] :conc-name [Keyword] concatenate [Function] cond [Special, Macro] conjugate [Function] cons [Function] :console [Keyword] Added. consp [Function] constantp [Function] :constructor [Keyword] :copier [Keyword] copy-alist [Function] copy-list [Function] copy-readtable [Function] copy-seq [Function] copy-symbol [Function] copy-tree [Function] cos [Function] cosh [Function] count [Function] :count [Keyword] count-if [Function] count-if-not [Function] :create [Keyword] ctypecase [Macro]
:current [Keyword] Break Loop Command. :data [Keyword] Added. :data-file [Keyword] Added. :debug [Keyword] Added. *debug-io* [Variable] decf [Special, Macro] declaration [Symbol] Declaration Specifier. declare [Special] decode-float [Function] decode-universal-time [Function] :default [Keyword] *default-pathname-defaults* [Variable] :defaults [Keyword] defautoload [Macro] Added. defcfun [Macro] Added. defconstant [Macro] defentry [Macro] Added. define-modify-macro [Macro] define-setf-method [Macro] defla [Macro] Added. defmacro [Special, Macro] defparameter [Macro] defsetf [Macro] defstruct [Macro] deftype [Macro] defun [Special, Macro] defvar [Macro] delete [Function] delete-duplicates [Function] delete-file [Function] delete-if [Function] delete-if-not [Function] denominator [Function] deposit-field [Function] describe [Function] :device [Keyword] digit-char [Function] digit-char-p [Function] :dir [Keyword] Added. :direction [Keyword]
directory [Function] :directory [Keyword] directory-namestring [Function] disassemble [Function] Different. :displaced-index-offset [Keyword] :displaced-to [Keyword] do [Special, Macro] do* [Special, Macro] do-all-symbols [Macro] do-external-symbols [Macro] do-symbols [Macro] documentation [Function] dolist [Special, Macro] dotimes [Special, Macro] double-float-epsilon [Constant] double-float-negative-epsilon [Constant] dpb [Function] dribble [Function] ecase [Macro] ed [Function] Different. eighth [Function] :element-type [Keyword] elt [Function] encode-universal-time [Function] :end [Keyword] :end1 [Keyword] :end2 [Keyword] endp [Function] enough-namestring [Function] &environment [Symbol] Defmacro-lambda Keyword. eq [Function] eql [Function] equal [Function] equalp [Function] error [Function] :error [Keyword] *error-output* [Variable] :escape [Keyword] etypecase [Macro] eval [Function]
evalhook [Function] *evalhook* [Variable] eval-when [Macro] *eval-when-compile* [Variable] Added. evenp [Function] every [Function] exp [Function] export [Function] expt [Function] :external [Keyword] :fasl-file [Keyword] Added. fboundp [Function] fceiling [Function] *features* [Variable] ffloor [Function] fifth [Function] file-author [Function] file-length [Function] file-namestring [Function] file-position [Function] file-write-date [Function] fill [Function] fill-pointer [Function] :fill-pointer [Keyword] find [Function] find-all-symbols [Function] find-if [Function] find-if-not [Function] find-package [Function] find-symbol [Function] finish-output [Function] first [Function] flet [Special] float [Function] float-digits [Function] float-precision [Function] float-radix [Function] float-sign [Function] floatp [Function] floor [Function]
fmakunbound [Function] force-output [Function] format [Function] fourth [Function] fresh-line [Function] :from-end [Keyword] fround [Function] ftruncate [Function] ftype [Symbol] Declaration Specifier. funcall [Function] function [Special] Also Declaration Specifier. functionp [Function] :functions [Keyword] Break Loop Command. gbc [Function] Added. gcd [Function] gensym [Function] :gensym [Keyword] gentemp [Function] get [Function] get-decoded-time [Function] get-dispatch-macro-character [Function] get-internal-real-time [Function] get-internal-run-time [Function] get-macro-character [Function] get-output-stream-string [Function] get-properties [Function] get-setf-method [Function] get-setf-method-multiple-value [Function] get-universal-time [Function] getf [Function] gethash [Function] go [Special] graphic-char-p [Function] hash-table-count [Function] hash-table-p [Function] :h [Keyword] Abbreviated Break Loop Command. :help [Keyword] Break Loop Command. :h-file [Keyword] Added. :hide [Keyword] Break Loop Command. :hide-package [Keyword] Break Loop Command. :host [Keyword]
host-namestring [Function] identity [Function] if [Special] :if-does-not-exist [Keyword] :if-exists [Keyword] ignore [Symbol] Declaration Specifier. *ignore-maximum-pages* [Variable] Added. imagpart [Function] import [Function] in-package [Function] incf [Special, Macro] :include [Keyword] :index [Keyword] :inherited [Keyword] :initial-contents [Keyword] :initial-element [Keyword] :initial-offset [Keyword] :initial-value [Keyword] inline [Symbol] Declaration Specifier. :input [Keyword] input-stream-p [Function] inspect [Function] int-char [Function] integer-decode-float [Function] integer-length [Function] integerp [Function] intern [Function] :intern [Keyword] internal-time-units-per-second [Constant] intersection [Function] :io [Keyword] :ioc [Keyword] Added. isqrt [Function] :junk-allowed [Keyword] :key [Keyword] keywordp [Function] :l [Keyword] Abbreviated Break Loop Command. labels [Special] lambda-list-keywords [Constant] lambda-parameters-limit [Constant]
last [Function] last-termination-message [Function] Added. lcm [Function] ldb [Function] ldb-test [Function] ldiff [Function] least-negative-double-float [Constant] least-negative-long-float [Constant] least-negative-short-float [Constant] least-negative-single-float [Constant] least-positive-double-float [Constant] least-positive-long-float [Constant] least-positive-short-float [Constant] least-positive-single-float [Constant] length [Function] :length [Keyword] let [Special] let* [Special] :level [Keyword] lisp-implementation-type [Function] lisp-implementation-version [Function] list [Function] :list [Keyword] Added. list* [Function] list-all-packages [Function] list-length [Function] listen [Function] Different. listp [Function] load [Function] *load-verbose* [Variable] :local [Keyword] Break Loop Command. locally [Special, Macro] log [Function] logand [Function] logandc1 [Function] logandc2 [Function] logbitp [Function] logcount [Function] logeqv [Function] logior [Function]
lognand [Function] lognor [Function] lognot [Function] logorc1 [Function] logorc2 [Function] logtest [Function] logxor [Function] long-float-epsilon [Constant] long-float-negative-epsilon [Constant] long-site-name [Function] loop [Special, Macro] lower-case-p [Function] machine-instance [Function] machine-type [Function] machine-version [Function] macro-function [Function] macroexpand [Function] macroexpand-1 [Function] *macroexpand-hook* [Variable] macrolet [Special] make-array [Function] make-broadcast-stream [Function] make-char [Function] make-concatenated-stream [Function] make-dispatch-macro-character [Function] make-echo-stream [Function] make-hash-table [Function] make-list [Function] make-package [Function] make-pathname [Function] make-random-state [Function] make-sequence [Function] make-string [Function] make-string-input-stream [Function] make-string-output-stream [Function] make-symbol [Function] make-synonym-stream [Function] make-two-way-stream [Function] makunbound [Function] map [Function]
mapc [Function] mapcan [Function] mapcar [Function] mapcon [Function] maphash [Function] mapl [Function] maplist [Function] mask-field [Function] max [Function] maximum-allocatable-pages [Function] Added. maximum-contiguous-pages [Function] Added. member [Function] member-if [Function] member-if-not [Function] merge [Function] merge-pathnames [Function] min [Function] minusp [Function] mismatch [Function] mod [Function] *modules* [Variable] most-negative-double-float [Constant] most-negative-fixnum [Constant] most-negative-long-float [Constant] most-negative-short-float [Constant] most-negative-single-float [Constant] most-positive-double-float [Constant] most-positive-fixnum [Constant] most-positive-long-float [Constant] most-positive-short-float [Constant] most-positive-single-float [Constant] multiple-value-bind [Special, Macro] multiple-value-call [Special] multiple-value-list [Special, Macro] multiple-value-prog1 [Special] multiple-value-setq [Special, Macro] multiple-values-limit [Constant] :n [Keyword] Abbreviated Break Loop Command. :name [Keyword] name-char [Function]
:named [Keyword] namestring [Function] nbutlast [Function] nconc [Function] :new-version [Keyword] :next [Keyword] Break Loop Command. nil [Constant] nintersection [Function] ninth [Function] not [Function] notany [Function] notevery [Function] notinline [Symbol] Declaration Specifier. nreconc [Function] nreverse [Function] nset-difference [Function] nset-exclusive-or [Function] nstring-capitalize [Function] nstring-downcase [Function] nstring-upcase [Function] nsublis [Function] nsubst [Function] nsubst-if [Function] nsubst-if-not [Function] nsubstitute [Function] nsubstitute-if [Function] nsubstitute-if-not [Function] nth [Function] nthcdr [Function] null [Function] numberp [Function] numerator [Function] nunion [Function] :ob-file [Keyword] Added. object [Symbol] Declaration Specifier. Added. oddp [Function] :o-file [Keyword] Added. open [Function] Different. optimize [Symbol] Declaration Specifier. or [Special, Macro]
:output [Keyword] :output-file [Keyword] output-stream-p [Function] :overwrite [Keyword] *package* [Variable] package-name [Function] package-nicknames [Function] package-shadowing-symbols [Function] package-use-list [Function] package-used-by-list [Function] packagep [Function] pairlis [Function] :parent [Keyword] Added. parse-integer [Function] parse-namestring [Function] pathname [Function] pathname-device [Function] pathname-directory [Function] pathname-host [Function] pathname-name [Function] pathname-type [Function] pathname-version [Function] pathnamep [Function] peek-char [Function] phase [Function] pi [Constant] plusp [Function] pop [Macro] position [Function] position-if [Function] position-if-not [Function] pprint [Function] :p [Keyword] Abbreviate Break Loop Command. :predicate [Keyword] :preserve-whitespace [Keyword] :pretty [Keyword] :previous [Keyword] Break Loop Command. prin1 [Function] prin1-to-string [Function]
princ [Function] princ-to-string [Function] print [Function] :print [Keyword] *print-array* [Variable] *print-base* [Variable] *print-case* [Variable] *print-circle* [Variable] *print-escape* [Variable] :print-function [Keyword] *print-gensym* [Variable] *print-length* [Variable] *print-level* [Variable] *print-pretty* [Variable] *print-radix* [Variable] :probe [Keyword] probe-file [Function] process [Function] Added. proclaim [Function] proclamation [Function] Added. prog [Special, Macro] prog* [Special, Macro] prog1 [Special, Macro] prog2 [Special, Macro] progn [Special] progv [Special] provide [Function] psetf [Macro] psetq [Special, Macro] push [Special, Macro] pushnew [Macro] :q [Keyword] Abbreviated Break Loop Command. *query-io* [Variable] :quit [Keyword] Break Loop Command. quote [Special] :r [Keyword] Abbreviated Break Loop Command. :radix [Keyword] random [Function] *random-state* [Variable] random-state-p [Function] rassoc [Function]
rassoc-if [Function] rassoc-if-not [Function] rational [Function] rationalize [Function] rationalp [Function] read [Function] *read-base* [Variable] read-byte [Function] Different. read-char [Function] read-char-no-hang [Function] Different. *read-default-float-format* [Variable] read-delimited-list [Function] read-from-string [Function] read-line [Function] :read-only [Keyword] read-preserving-whitespace [Function] *read-suppress* [Variable] *readtable* [Variable] readtablep [Function] realpart [Function] reduce [Function] :rehash-size [Keyword] :rehash-threshold [Keyword] rem [Function] remf [Macro] remhash [Function] remove [Function] remove-duplicates [Function] remove-if [Function] remove-if-not [Function] remprop [Function] :rename [Keyword] :rename-and-delete [Keyword] rename-file [Function] rename-package [Function] replace [Function] require [Function] :resume [Keyword] Break Loop Command. rest [Function] return [Special, Macro]
return-from [Special] revappend [Function] reverse [Function] room [Function] :root [Function] Added. rotatef [Macro] round [Function] rplaca [Function] rplacd [Function] safety [Symbol] Optimize Quality. save [Function] Added. sbit [Function] scale-float [Function] schar [Function] search [Function] second [Function] set [Function] set-char-bit [Function] set-difference [Function] set-dispatch-macro-character [Function] set-exclusive-or [Function] set-macro-character [Function] set-syntax-from-char [Function] setf [Special, Macro] setq [Special] seventh [Function] shadow [Function] shadowing-import [Function] shiftf [Macro] short-float-epsilon [Constant] short-float-negative-epsilon [Constant] short-site-name [Function] signum [Function] simple-bit-vector-p [Function] simple-string-p [Function] simple-vector-p [Function] sin [Function] single-float-epsilon [Constant] single-float-negative-epsilon [Constant] sinh [Function]
sixth [Function] :size [Keyword] sleep [Function] software-type [Function] software-version [Function] some [Function] sort [Function] space [Symbol] Optimize Quality. special [Symbol] Declaration Specifier. special-form-p [Function] speed [Symbol] Optimize Quality. sqrt [Function] stable-sort [Function] standard-char-p [Function] *standard-input* [Variable] *standard-output* [Variable] :start [Keyword] :start1 [Keyword] :start2 [Keyword] :static [Keyword] Added. step [Macro] :stream [Keyword] stream-element-type [Function] streamp [Function] string [Function] string-capitalize [Function] string-char-p [Function] string-downcase [Function] string-equal [Function] string-greaterp [Function] string-left-trim [Function] string-lessp [Function] string-not-equal [Function] string-not-greaterp [Function] string-not-lessp [Function] string-right-trim [Function] string-trim [Function] string-upcase [Function] string/= [Function] string< [Function]
string<= [Function] string= [Function] string> [Function] string>= [Function] stringp [Function] sublis [Function] subseq [Function] subsetp [Function] subst [Function] subst-if [Function] subst-if-not [Function] substitute [Function] substitute-if [Function] substitute-if-not [Function] subtypep [Function] :supersede [Keyword] svref [Function] sxhash [Function] symbol-function [Function] symbol-name [Function] symbol-package [Function] symbol-plist [Function] symbol-value [Function] symbolp [Function] system [Function] Added. t [Constant] :tags [Keyword] Break Loop Command. tagbody [Special] tailp [Function] tan [Function] tanh [Function] tenth [Function] *terminal-io* [Variable] Different. termination-message [Function] Added. terpri [Function] :test [Keyword] :test-not [Keyword] the [Special] third [Function] throw [Special]
time [Macro] trace [Macro] *trace-output* [Variable] tree-equal [Function] truename [Function] truncate [Function] type [Symbol] Declaration Specifier. :type [Keyword] type-of [Function] typecase [Macro] typep [Function] unexport [Function] unintern [Function] union [Function] :unhide [Keyword] Break Loop Command. :unhide-package [Keyword] Break Loop Command. unless [Special, Macro] unread-char [Function] untrace [Macro] unuse-package [Function] unwind-protect [Special] upper-case-p [Function] use-package [Function] user-homedir-pathname [Function] :username [Keyword] Added. :v [Keyword] Abbreviated Break Loop Command. values [Function] values-list [Function] :variables [Keyword] Break Loop Command. vector [Function] vector-pop [Function] vector-push [Function] vector-push-extend [Function] vectorp [Function] :verbose [Keyword] :version [Keyword] warn [Function] when [Special, Macro] &whole [Symbol] Defmacro-lambda Keyword. :wild [Keyword] Added. with-input-from-string [Macro]
with-open-file [Macro] with-open-stream [Macro] with-output-to-string [Macro] write [Function] write-byte [Function] Different. write-char [Function] write-line [Function] write-string [Function] write-to-string [Function] y-or-n-p [Function] yes-or-no-p [Function] zerop [Function]
Kyoto Common Lisp (KCL for short) is a full implementation of the Common Lisp language. KCL is a highly portable Common Lisp system intended for several classes of machines, from mini/micro to mainframe. The key idea behind the portability is the use of the C language and its standard libraries as the interface with the underlying machines and operating systems: The kernel of the system is written in C and the rest of the system is written in Common Lisp. Even the compiler generates intermediate code in C. KCL is also an efficient and compact system: KCL regards the runtime efficiency of interpreted code as important as the efficiency of compiled code. The small size of the KCL system makes KCL suitable for the current computer technology, such as the use of virtual memory and cache memory. This document reports the current status of KCL, its implementation, and system performance. This document is a draft: the description is still incomplete and informal, and some technical terms are used without definition or explanation. A full paper on the KCL implementation is in preparation.
KCL is a full Common Lisp system.
KCL is a full implementation of the Common Lisp language described in the Common Lisp Reference Manual:
KCL supports all Common Lisp functions, macros, and special forms defined in the Common Lisp Reference Manual. All Common Lisp variables and constants are defined in KCL exactly as described in the Common Lisp Reference Manual.
KCL is available on several machines already.
Currently, there are four major versions of KCL:
KCL/AOS is the original version of KCL, which was developed at Research Institute for Mathematical Sciences (RIMS), Kyoto University, with the cooperation of Nippon Data General Corporation. Other versions are ported from KCL/AOS at RIMS. All four versions share most of the source files of KCL. Improvements and error corrections are performed on the common source files, and the most recent revisions are brought to each machine from time to time.
Ports to other machines and other operating systems are being undertaken or are in preparation at other organizations. KCL is expected to become available on the following machines in the near future.
KCL is written in C and Lisp
The kernel of KCL is written in C, including:
The KCL compiler is entirely written in Common Lisp.
Each Common Lisp function or macro is written either in C or in Lisp.
in C: 418 Common Lisp functions 11 Common Lisp macros in Lisp: 133 Common Lisp functions 59 Common Lisp macros
The size of the source code is:
C code 705 Kbytes Common Lisp functions and macros written in Lisp 173 Kbytes The compiler 264 Kbytes --------------------------- total 1142 Kbytes
Three routines in the kernel are partly written in assembly language. These routines are:
The total size of assembly code is 20 to 30 lines, depending on the version of KCL.
KCL/AOS is built up by old-fashioned bootstrapping
When KCL/AOS, the original version of KCL, was born, the following steps were taken to build it up.
The same steps are taken whenever drastic changes are made to the kernel. On the other hand, the procedure to port KCL or to revise the ported versions of KCL is much simpler, because all Lisp code has been cross-compiled by the compiler of KCL/AOS beforehand.
Objects are represented by cells.
KCL does not support the so-called immediate data. Any KCL object is represented as (a pointer to) a cell that is allocated on the heap. Each cell consists of several words (1 word = 32 bit) whose first word is in the format common to all data types: half of the word is the type indicator and the other half is used as the mark by the garbage collector. For instance, a cons cell consists of three words:
|----------|-----------| | `CONS' | mark-bit | |----------|-----------| | car-pointer | |----------------------| | cdr-pointer | |----------------------|
and a fixnum cell consists of two words:
|----------|-----------| | 'FIXNUM' | mark-bit | |----------|-----------| | fixnum-value | |----------------------|
Array headers and compiled-function headers are represented in this way, and array elements and compiled code are placed elsewhere.
Internally in compiled functions, certain Lisp objects may be represented simply by their values. For example, a fixnum object may be represented by its fixnum value, and a character object may be represented by its character code.
Cells of small fixnums ranging from -1024 to 1023 and cells of characters are pre-allocated in fixed locations. Thus, for example,
yields t , whereas
yields nil.
The heap is divided into pages.
The whole heap of KCL is divided into pages (1 page = 2048 bytes). Each page falls in one of the following classes:
Free cells (i.e., those cells that are not used any more) consisting of the same number of words are linked together to form a free list. When a new cell is requested, the first cell in the free list (if it is not empty) is used and is removed from the list. If the free list is empty, then the garbage collector begins to run to collect unused cells. If the new free list is too short after the garbage collection, then new pages are allocated dynamically. Free binary data are also linked together in the order of the size so that, when a binary datum is being allocated on the heap, the smallest free area that is large enough to hold the binary datum will be used. Cell pages are never compactified. Once a page is allocated for cells with n words, the page is used for cells with n words only, even after all the cells in the page become garbage. The same rule holds for binary pages. In contrast, relocatable pages are sometimes compactified. That is, each relocatable datum may be moved to another place.
The actual configuration of the KCL heap is:
There is a ``hole'' between the area for cell/binary pages and the area for relocatable pages. New pages are allocated in the hole for cell/binary pages, whereas new relocatable pages are allocated by expanding the heap to the higher address, i.e., to the right in this figure. When the hole becomes empty, the area for relocatable pages are shifted to the right to reserve a certain number of pages as the hole. During this process, the relocatable data in the relocatable pages are compactified. No free list is maintained for relocatable data.
Symbol print names and string bodies are usually allocated in relocatable
pages. However, when the KCL system is created, i.e., when the object module
of KCL is created, such relocatable data are moved towards the area for
cell/binary pages and then the pages for relocatable data are
marked ``static''. The garbage collector never tries to sweep static
pages. Thus, within the object module of KCL, the heap looks like:
Notice that the hole is not included in the object module; it is allocated only when the KCL system is started. This saves secondary storage a little bit. The maximum size of the hole is about 100 pages (= 200 Kbytes).
KCL uses five stacks.
KCL uses the following stacks.
Arguments/values are passed via the value stack.
To show the argument/value passing mechanism, here we list the actual code for the Common Lisp function cons .
Lcons() { object x; check_arg(2); x = alloc_object(t_cons); x->c.c_car = vs_base[0]; x->c.c_cdr = vs_base[1]; vs_base[0] = x; vs_pop; }
We adopted the convention that the name of a function that implements a Common Lisp function begins with ` L ', followed by the name of the Common Lisp function. (Strictly speaking, `-' and ` * ' in the Common Lisp function name are replaced by `_' and ` A ', respectively, to obey the syntax of C.) Arguments to functions are pushed on the value stack. The stack pointer vs_base (value stack base) points to the first argument and another pointer vs_top points to the stack location next to the last argument. Thus, for example, when cons is called with the first argument 1 and the second argument 2 , the value stack looks like:
|---------| vs_top ->| | |---------| | 2 | |---------| vs_base ->| 1 | |---------| | | : : | | bottom |---------| value stack
check_arg(2) in the code of Lcons checks if exactly two arguments are supplied to cons . That is, it checks whether the difference of vs_top and vs_base is 2 , and if not, it causes an error. allocate_object(t_cons) allocates a cons cell in the heap and returns the pointer to the cell. After the car and the cdr fields of the cell are set, the cell pointer is put onto the value stack. The two stack pointers are used also on return from a function call. vs_base points to the first returned value and vs_top points to the stack location next to the last returned value. vs_pop in the code above decrements vs_top by one.
|---------| | | |---------| vs_top ->| | |---------| vs_base ->| (1 . 2) | |---------| | | : : | | bottom |---------| value stack
Because the same stack pointers are used both for argument passing and for return value passing, the Common Lisp function values does almost nothing.
On the call of (values 1 2) On return from (values 1 2) |---------| |---------| vs_top ->| | vs_top ->| | |---------| |---------| | 2 | | 2 | |---------| |---------| vs_base ->| 1 | vs_base ->| 1 | |---------| |---------| | | | | : : : : | | | | bottom |---------| bottom |---------| value stack value stack
In most cases, the caller of a function uses only the first returned value which is pointed to by vs_base . This is not the case, however, when the called function returns no value at all. In order to avoid the check whether this is the case, each KCL function, on return from its call, sets nil to the stack entry which is pointed to by vs_base , whenever it returns no value at all. Thus, for instance, the actual code for the Common Lisp function values is:
Lvalues() { vs_top[0] = Cnil; }
where Cnil is a global variable that always contains the pointer to nil. See why this works.
The interpreter uses A-lists.
The KCL interpreter uses three A-lists (Association lists) to represent lexical environments.
When a function closure is created, the current three A-lists are saved in the closure along with the lambda expression. Later, when the closure is invoked, the saved A-lists are used to recover the lexical environment.
The invocation history stack is used for debugging.
The invocation history stack consists of two kinds of elements. Each element may be either a pair of a Lisp form and a pointer to lexical environment:
or a pair of a function name and a pointer to the value stack:
The former is pushed on the invocation history stack when an interpreted code is evaluated. The form is the interpreted code itself and the environment-pointer points to the three consecutive memory words each of which holds the A-list that represents the lexical environment. The latter is pushed when a compiled function is invoked. The function-name is the name of the called function and the value-stack-pointer points to the value stack location which is pointed to by vs_base when the function is called. For both kinds, the element on the invocation history stack is poped at the end of the evaluation.
Let us see how the invocation history stack is used for debugging.
>(defun fact (x) ;;; Wrong definition of the (if (= x 0) ;;; factorial function. one ;;; one should be 1 . (* x (fact (1- x))))) fact >(fact 3) ;;; Tries 3! Error: The variable ONE is unbound. Error signalled by IF. Broken at IF. >>:b ;;; Backtrace. Backtrace: eval > fact > if > fact > if > fact > if > fact > IF ;;; Currently at the last if. >>:h ;;; Help. :c(urrent) Show current function. :p(revious) Move to previous function. :n(ext) Move to next function. :b(acktrace) Backtrace. :h(elp) Help. :q(uit) Return to top-level. :r(esume) Return to the caller :l(ocal) Show n-th local value. :v(ariables) Show local variables. :functions Show local functions. :blocks Show block names. :tags Show tags. :hide Hide a function :hide-package Hide a package. :unhide Unhide a function :unhide-package Unhide a package. >>:p ;;; Move to the last call of fact. Broken at FACT. >>:b Backtrace: eval > fact > if > fact > if > fact > if > FACT > if ;;; Now at the last fact. >>:v ;;; The environment at the last call Local variables: x. ;;; to fact is recovered. ;;; x is the only bound variable. >>x 0 ;;; The value of x is 0. >>:blocks Block names: fact. ;;; The block fact is established. >>(return-from fact 1) ;;; Return from the last call of 6 ;;; fact with the value of 0. ;;; The execution is resumed and > ;;; the value 6 is returned. ;;; Again at the top-level loop.
The KCL compiler generates intermediate code in C.
The KCL compiler is essentially a translator from Common Lisp to C. Given a Lisp source file, the compiler first generates three intermediate files:
The KCL compiler then invokes the C compiler to compile the C-file into an object file. Finally, the contents of the Data-file is appended to the object file to make a Fasl-file. The generated Fasl-file can be loaded into the KCL system by the Common Lisp function load. By default, the three intermediate files are deleted after the compilation, but, if asked, the compiler leaves them.
The merits of the use of C as the intermediate language are:
The demerits are:
The compiler mimics human C programmer.
The format of the intermediate C code generated by the KCL compiler is the same as the hand-coded C code of the KCL source programs. For example, supposing that the Lisp source file contains the following function definition:
(defun add1 (x) (1+ x))
The compiler generates the following intermediate C code.
init_code(start,size,data)char *start;int size;object data; { register object *base=vs_top; register object *sup=base+VM2; vs_check; Cstart=start;Csize=size;Cdata=data; set_VV(VV,VM1,data); MF(VV[0],L1,start,size,data); vs_top=vs_base=base; } /* function definition for ADD1 */ static L1() { register object *base=vs_base; register object *sup=base+VM3; vs_reserve(VM3); check_arg(1); vs_top=sup; base[1]=one_plus(base[0]); vs_top=(vs_base=base+1)+1; return; }
The C function L1 implements the Lisp function add1. This relation is established by MF in the initialization function init_code , which is invoked at load time. There, the vector VV consists of Lisp objects; VV[0] in this example holds the Lisp symbol add1. VM3 in the definition of L1 is a C macro declared in the corresponding H-file. The actual value of VM3 is the number of value stack locations used by L1, i.e., 2 in this example. Thus the following macro definition is found in the H-file.
#define VM3 2\\
When the compiled add1 is called, the value stack looks like:
On the call of (add1 1) On return from (add1 1) |---------| |---------| | | vs_top -> | | |---------| |---------| vs_top ->| | vs_base ->| 2 | |---------| |---------| vs_base ->| 1 | | 1 | |---------| |---------| | | | | : : : : | | | | bottom |---------| bottom |---------| value stack value stack
Note that the two value stack pointers need not be moved in this example. This shows that the KCL compiler still has room for improvement.
Lexical environment of compiled closures is represented by a
list.
The KCL compiler takes two passes before it invokes the C compiler. The major role of the first pass is to detect function closures and to detect, for each function closure, those lexical objects (i.e., lexical variable, local function definitions, tas, and block-names) to be enclosed within the closure. This check must be done before the C code generation in the second pass, because lexical objects to be enclosed in function closures are treated in a different way from those not enclosed.
Ordinarily, lexical variables in a compiled function f are allocated on the value stack. However, if a lexical variable is to be enclosed in function closures, it is allocated on a list, called the "environment list", which is local to f. In addition, one entity is reserved on the value stack, in which the pointer to the variable's location (within the environment list) is stored, so that the variable may be accessed by indexing rather than by list traversal. The environment list is a pushdown list: It is empty when f is called. An element is pushed on the environment list when a variable to be enclosed in closures is bound, and is popped when the binding is no more in effect. That is, at any moment during execution of f, the environment list contains those lexical variables whose binding is still in effect and which should be enclosed in closures. When a compiled closure is created during execution of f, the compiled code for the closure is coupled with the environment list at that moment to form the compiled closure. Later, when the compiled closure is invoked, as many entities as the elements in the environment list is reserved on the value stack, each of which points to a lexical object in the environment list, so that, again, each object may be referenced by indexing.
Let us see an example. Suppose the following function has been compiled.
(defun foo (x) (let ((a \#'(lambda () (incf x))) (y x)) (values a \#'(lambda () (incf x y)))))
foo returns two compiled closures. The first closure increments x by one, whereas the second closure increments x by the initial value of x. Both closures return the incremented value of x.
>(multiple-value-setq (f g) (foo 10)) \#<compiled-closure nil> >(funcall f) 11 >(funcall g) 21 >
After this, the two compiled closures look like:
second closure y: x: |-------|------| |-------|------| |------|------| | ** | --|----->| 10 | --|------>| 21 | nil | |-------|------| |-------|------| |------|------| ^ first closure | |-------|------| | | * | --|----------| |-------|------| * : address of the compiled code for #'(lambda () (incf x)) ** : address of the compiled code for #'(lambda () (incf x y))
Declarations increase code efficiency.
Declarations, especially type and function declarations, increase the efficiency of the compiled code. For example, for the following Lisp source file, with two Common Lisp declarations added,
(eval-when (compile) (proclaim '(function tak (fixnum fixnum fixnum) fixnum)) (defun tak (x y z) (declare (fixnum x y z)) (if (not (< y x)) z (tak (tak (1- x) y z) (tak (1- y) z x) (tak (1- z) x y))))
the compiler generates the following C code.
/* local entry for function TAK */ static int LI2(V4,V5,V6) int V4,V5,V6; { VMB3 VMS3 VMV3 if((V5)<(V4)){ goto T4;} VMR3(V6) T4:; {int V7=LI2((V4)-1,V5,V6); {int V8=LI2((V5)-1,V6,V4); VMR3(LI2(V7,V8,LI2((V6)-1,V4,V5)))}} } /* global entry for the function TAK */ static L2() { register object *base=vs_base; base[0]=make_fixnum(LI2(fix(base[0]), fix(base[1]), fix(base[2]))); vs_base=base; vs_top=base+1; }
The main part of the tak function is LI2 . If redundant parentheses are removed, macros are expanded, and identifiers are renamed, we obtain the following code equivalent to LI2 .
/* local entry for function TAK */ static int tak(x,y,z) int x,y,z; { if(y<x) goto L; return(z); L: { int t1=tak(x-1,y,z); int t2=tak(y-1,z,x); return(tak(t1,t2,tak(z-1,x,y))); } }
This is almost hand-written tak code in C. The only overhead is the use of the temporary variables t1 and t2. This is necessary to make sure that the arguments are evaluated in the correct order (i.e., from left to right), since the C language does not specify the order of argument evaluation. If the compiler generated the following code,
return(tak(tak(x-1,y,z),tak(y-1,z,x),tak(z-1,x,y)));
the C compiler of Eclipse AOS/VS evaluates the three inner calls to tak from left to right (this is all right), whereas the C compiler of Unix evaluates from right to left (this is bad). In this example of tak , the order of evaluation does not matter actually, because tak causes no side effects. But the KCL compiler does not know that. The KCL compiler still has room for improvements.
KCL does not have ``disassembler''.
Common Lisp defines a function disassemble , which is supposed to disassemble a compiled function and to display the assembler code. According to the Common Lisp Reference Manual,
This is primary useful for debugging the compiler, ..
This is, however, useless in our case, because we are not concerned with assembly language. Rather, we are interested in the C code generated by the KCL compiler. Thus the disassemble function in KCL accepts not-yet-compiled functions only and displays the translated C code.
>(defun add1 (x) (1+ x)) add1 >(disassemble 'add1) init_code(start,size,data)char *start;int size;object data; { register object *base=vs_top; register object *sup=base+VM2; vs_check; Cstart=start;Csize=size;Cdata=data;set_VV(VV,VM1,data); MF(VV[0],L1,start,size,data); vs_top=vs_base=base; } /* function definition for ADD1 */ static L1() { register object *base=vs_base; register object *sup=base+VM3; vs_check; vs_top=sup; base[1]=one_plus(base[0]); vs_top=(vs_base=base+1)+1; return; } >
KCL/AOS has its own screen editor.
KCL/AOS has an embedded full-screen editor which resembles EMACS. The editor is called FeCl2 as the acronym of Full-screen Editor as a Common Lisp TOOl. It is invoked by the Common Lisp function ed. Unfortunately, FeCl2 is not supported by other versions of KCL, simply because we are too lazy to port it (it is written in C). For these versions, ed invokes the vi editor of Unix.
KCL has C language interface.
The user can embed his or her own C code into Lisp source code. The idea is very simple: The specified C code is inserted in the intermediate C code that is generated by the KCL compiler. In the following example, Clines and defentry are top-level macros specific to KCL. The Clines macro form specifies the C code to be embedded, in terms of strings, and the defentry form defines an entry of the specified C function from KCL.
(Clines " int tak(x, y, z) " " int x, y, z; " " { if (y >= x) return(z); " " else return(tak(tak(x-1, y, z), " " tak(y-1, z, x), " " tak(z-1, x, y))); " " } " ) (defentry tak (int int int) (int "tak"))
Port to VAX took three days.
Although KCL is made to be highly portable, certain minor changes had to be done, when it was ported to VAX Unix 4.2 bsd. These changes include:
most-positive-short-float most-negative-short-float least-positive-short-float least-negative-short-float most-positive-long-float most-positive-double-float most-positive-single-float most-negative-long-float most-negative-double-float most-negative-single-float least-positive-long-float least-positive-double-float least-positive-single-float least-negative-long-float least-negative-double-float least-negative-single-float short-float-epsilon short-float-negative-epsilon long-float-epsilon double-float-epsilon single-float-epsilon long-float-negative-epsilon double-float-negative-epsilon single-float-negative-epsilon
decode-float scale-float float-radix float-digits float-precision integer-decode-float
The whole job of poring KCL to VAX Unix 4.2 bsd took three days. Later, we spent some more days, to fix bugs in the ported version of KCL.
Port to SUN took three evenings.
The port to the SUN Workstation was much easier than the port to the VAX, mainly because the operating system is the same for both VAX and SUN.
The whole job of poring KCL to SUN took three evenings. Most of the time was spent for the three assembler routines, because we did not know anything about the MC68000 assembler at first.
Port to Ustation took one week.
The port to the Ustation was relatively a hard job. It took almost a week. The major difficulity was that the C compiler of Unix V on the Ustation recognized identifiers only by the first seven characters. As already mentioned, we used the convention that the C function that implements the Common Lisp function function-name is given the name L function-name . Thus, for example, the Common Lisp functions on packages such as
package-name package-nickname package-shadowing-symbols package-use-list package-used-by-list packagep
are implemented by the C functions whose names all begin with Lpackage . These C functions are regarded as having the same name by the C compiler. This problem was solved by preparing a preprocessor program which maps long identifiers into smaller ones. This program is now used by the KCL compiler on Ustation before the C compiler is called.
KCL is relatively compact.
The size of the object module of the whole KCL system (including the Compiler) is
KCL/AOS 1.78 Mbytes KCL/VAX 1.45 Mbytes KCL/SUN 1.56 Mbytes KCL/UST 1.56 Mbytes
Since all system initialization (such as loading the database of the KCL compiler) has been done when the object module is created, the object module size roughly corresponds to the initial size of the KCL process when a KCL session is started, minus the initial size of the hole in the heap (about 200 Kbytes).
Gabriel's benchmark.
The following table shows the results of Richard Gabriel's Lisp benchmark tests with the four versions of KCL. The results with five other Common Lisp systems are also listed for comparison. Each number represents the CPU time (in seconds) for the compiled program. ` * ' indicates that the time includes garbage-collection time. The data of S-1 Lisp and Spice Lisp are found in:
We received the data of Symbolics, DEC Common Lisp, and DG Common Lisp directly from Dr. Richard Gabriel in April 1985. We measured the data for KCL in July 1985. For the details of the benchmark tests, refer to the book above.
Benchmark | Boyer | Browse | Destruct | Traverse | Traverse |
Test | Initialize | Run | |||
Kyoto CL | 11.02 | 18.09 | 3.15 | 5.75 | 44.16 |
MV10000 | |||||
Kyoto CL | 43.73 | 68.15* | 8.00 | 14.42 | 151.20 |
VAX 780 | |||||
Kyoto CL | 43.60* | 73.08* | 10.23 | 20.38 | 118.60 |
E15 | |||||
Kyoto CL | 47.00 | 81.37 | 14.10 | 26.30 | 160.58 |
SUN | |||||
Symbolics | 11.99 | 30.8 | 3.03 | 8.62 | 49.95 |
3600 | |||||
S-1 CL | 10.03 | 10.2 | 0.91 | 1.93 | 30.1 |
Mark IIA | |||||
Spice | 134.79 | 359.63 | 17.78 | 41.75 | 490.6 |
Perq | |||||
DEC CL | 46.79 | 118.51 | 6.38 | 20.76 | 161.68 |
VAX 780 | |||||
DG CL | 29.3 | 59.91 | 6.95 | 27.77 | 45.86 |
MV10000 |
Benchmark | Tak | Stak | Ctak | Takl | Takr |
Test | |||||
Kyoto CL | 0.42 | 1.90 | 4.35 | 5.13 | 0.54 |
MV10000 | |||||
Kyoto CL | 1.45 | 6.03 | 14.02 | 19.97 | 1.75 |
VAX 780 | |||||
Kyoto CL | 1.17 | 7.63 | 9.58 | 16.10 | 1.38 |
E15 | |||||
Kyoto CL | 1.48 | 11.02 | 16.88 | 23.35 | 1.67 |
SUN | |||||
Symbolics | 0.6 | 2.58 | 7.65 | 6.44 | 0.6 |
3600 | |||||
S-1 CL | 0.29 | 4.31 | 0.82 | 2.92 | 0.58 |
Mark IIA | |||||
Spice | 4.7 | 13.5 | 8.4 | 24.0 | 7.7 |
Perq | |||||
DEC CL | 1.83 | 4.11 | 8.09 | 7.34 | 3.42 |
VAX 780 | |||||
DG CL | 0.89 | 3.09 | 1.79 | 5.52 | 1.21 |
MV10000 |
Benchmark | Deriv | DDeriv | Div2 | Div2 | FFT |
Test | Iterative | Recursive | |||
Kyoto CL | 4.85 | 5.93 | 1.99 | 2.73 | 1.55 |
MV10000 | |||||
Kyoto CL | 18.98 | 23.07 | 7.48 | 11.25 | 9.07 |
VAX 780 | |||||
Kyoto CL | 22.07* | 25.38* | 9.95* | 12.60* | 74.62 |
E15 | |||||
Kyoto CL | 20.72 | 24.77 | 9.32 | 12.30 | 94.07 |
SUN | |||||
Symbolics | 5.12 | 5.24 | 1.85 | 2.89 | 4.75 |
3600 | |||||
S-1 CL | 4.99 | 3.27 | 0.82 | 1.49 | 1.44 |
Mark IIA | |||||
Spice | 71.8 | 77.7 | 28.15 | 40.69 | 59.0 |
Perq | |||||
DEC CL | 13.76 | — | 5.0 | 9.84 | 32.69 |
VAX 780 | |||||
DG CL | 5.6 | 8.11 | 2.8 | 4.48 | 62.78 |
MV10000 |
Benchmark | Puzzle | Triang | Fprint | Fread | Tprint |
Test | |||||
Kyoto CL | 6.76 | 104.85 | 1.98 | 2.45 | 1.74 |
MV10000 | |||||
Kyoto CL | 20.57 | 366.12 | 5.73 | 5.77 | 6.55 |
VAX 780 | |||||
Kyoto CL | 41.30 | 341.23* | 9.83 | 6.07 | 11.58 |
E15 | |||||
Kyoto CL | 49.13 | 499.68 | 10.05 | 7.62 | 8.50 |
SUN | |||||
Symbolics | 13.89 | 151.7 | 2.6 | 4.6 | 4.9 |
3600 | |||||
S-1 CL | 1.82 | 62.06 | — | — | — |
Mark IIA | |||||
Spice | 75.14 | 1488.85 | 20.0 | 26.0 | 22.6 |
Perq | |||||
DEC CL | 47.48 | 360.85 | 3.94 | 7.24 | 2.85 |
VAX 780 | |||||
DG CL | 138.2 | 151.2 | 2.35 | 4.65 | 2.83 |
MV10000 |
This appendix explains how to install the KCL system, separately for each version of KCL.
C.1. Installation of KCL/AOS
1. Prepare a directory (hereafter called KCL directory) for Kyoto Common Lisp. In the following examples, we suppose that the KCL directory is :UDD:KCL.
2. Load the distribution tape to the KCL directory.
) DIR :UDD:KCL ) LOAD
You will find that the subdirectory PORT has been created. The PORT subdirectory contains everything that is needed to run KCL. Files in this directory are:
Documents: README this file Executable files: KCL.PR the KCL interpreter and compiler KCL.ST BUILD_FASL.PR the fasl-file builder FECL2.PR the FeCl2 editor Command files: KCL.CLI to invoke KCL LC.CLI to invoke the KCL compiler LC1.CLI to invoke the KCL compiler FECL2.CL1 to invoke the FeCl2 editor Header file: CMPINCLUDE.H the header file for the KCL compiler Miscellaneous: FECL2.CMD FeCl2 editor command table
3. Customize the command files.
The command file KCL.CLI consists of the following command lines to invoke the KCL interpreter.
push;prom pop sea :usr:dgc [!sea] x :udd:[!user]:port:%0-% :udd:[!user]:port: pop
Replace the two occurrences of " [!user] " with the name of the KCL directory (i.e., KCL in our example).
push;prom pop sea :usr:dgc [!sea] x :udd:KCL:port:%0-% :udd:KCL:port: pop
And move this file to an appropriate command directory, say :UTIL, so that all KCL users can access it.
If the name of the directory that includes DG's C compiler is not :USR:DGC, you should replace it with the appropriate directory name, so that the KCL compiler can access the C compiler by CC.PR.
You can use the commands LC.CLI and LC1.CLI to invoke the compiler directly from the CLI. The content of LC.CLI is:
push prompt pop level sea :usr:dgc [!sea] WRITE Compiling %1%.LSP. proc/def/ioc/block/pri=3 \& :udd:[!user]:port:kcl :udd:[!user]:port: \%1\% \%1\% U10000 pop
Customize these command files in the same way as for the KCL.CLI command file above.
4. Install the header file
Copy the header file CMPINCLUDE.H to the standard directory for C include files, say :USR:DGC.
C.2. Installation of KCL/VAX
1. Prepare a directory (hereafter called KCL directory) for Kyoto Common Lisp. In the following examples, we suppose that the KCL directory is /usr/kcl.
2. Load the distribution tape to the KCL directory.
% pwd usr/kcl % tar x
You will find that the subdirectory unixport has been created. The unixport subdirectory contains everything that is needed to run KCL and the KCL compiler. Files in this directory are:
Documents: readme this file Executable files: saved_kcl the KCL interpreter and compiler Command files: kcl to invoke KCL lc to invoke the KCL compiler lc1 to invoke the KCL compiler Header file: cmpinclude.h the header file for the KCL compiler
3. Customize the command files.
The command file kcl consists of a single line command to invoke the KCL interpreter.
# ~/unixport/saved_kcl ~/unixport/
Replace two ' 's with the pathname of the KCL directory (i.e., /usr/kcl in our example).
# /usr/kcl/unixport/saved_kcl /usr/kcl/unixport/
And move this file to an appropriate command directory, say /usr/bin, so that all KCL users can access it.
You can use the commands lc and lc1 to invoke the compiler directly from the shell. The content of lc is:
# echo Compiling $1.lsp ~/unixport/saved_kcl ~/unixport/ $1 $1 U1000
Customize these command files in the same way as for the kcl command file above.
4. Install the header file
Copy the header file cmpinclude.h to the standard directory for C include files, say /usr/include.
C.3. Installation of KCL/SUN
1. Prepare a directory (hereafter called KCL directory) for Kyoto Common Lisp. In the following examples, we suppose that the KCL directory is /usr/kcl.
2. Load the distribution tape to the KCL directory.
% pwd /usr/kcl % tar x
You will find that the subdirectory unixport has been created. The unixport subdirectory contains everything that is needed to run KCL and the KCL compiler. Files in this directory are:
Documents: readme this file Executable files: saved_kcl the KCL interpreter and compiler Command files: kcl to invoke KCL lc to invoke the KCL compiler lc1 to invoke the KCL compiler Header file: cmpinclude.h the header file for the KCL compiler
3. Customize the command files.
The command file kcl consists of a single line command to invoke the KCL interpreter.
# ~/unixport/saved_kcl ~/unixport/
Replace two ` 's with the pathname of the KCL directory (i.e., /usr/kcl in our example).
# /usr/kcl/unixport/saved_kcl /usr/kcl/unixport/
And move this file to an appropriate command directory, say /usr/bin, so that all KCL users can access it.
You can use the commands lc and lc1 to invoke the compiler directly from the shell. The content of lc is:
# echo Compiling $1.lsp ~/unixport/saved_kcl ~/unixport/ $1 $1 U1000
Customize these command files in the same way as for the kcl command file above.
4. Install the header file
Copy the header file cmpinclude.h to the standard directory for C include files, say /usr/include.
C.4. Installation of KCL/UST
1. Prepare a directory (hereafter called KCL directory ) for Kyoto Common Lisp. In the following examples, we suppose that the KCL directory is /usr/kcl.
2. Three floppy disks are used for the distribution. Load the floppy disks to the KCL directory by the multi-volume option of the tar command. (Insert the first disk to the drive and issue the tar command. Then, you will be prompted to change the disks.)
% pwd /usr/kcl % tar xvfBM /dev/rdy0g 1976
You will find that the subdirectory unixport has been created. The unixport subdirectory contains everything that is needed to run KCL and the KCL compiler. Files in this directory are:
Documents: readme this file Executable files: saved_kcl the KCL interpreter and compiler ild incremental loader trans translator from Unix 4.2 to Unix V Command Source files: kcl.c to invoke KCL lc.c to invoke the KCL compiler lc1.c to invoke the KCL compiler Header file: cmpinclude.h the header file for the KCL compiler
3. Customize the command files.
The source file kcl.c consists of a C-language program to invoke the KCL interpreter. Replace all /usr/ukcl in this file with the pathname of the KCL directory (i.e., /usr/kcl in our example), and compile this file.
% cc -o kcl kcl.c
And move the object file to an appropriate command directory, say /usr/bin , so that all KCL users can access it.
You can use the source files lc.c and lc1.c to invoke the compiler directly from the shell. Customize these source files in the same way as for the kcl command file above.
4. Install the header file
Copy the header file cmpinclude.h to the standard directory for C include files, say /usr/include.